#include "FrameClass.h"

void on_Bintrackbar(int argc,void* argv)
{
	FrameClass* obj = static_cast<FrameClass*>(argv);	
	obj->thresholdMin = cv::getTrackbarPos("Min Bbar","BIN");
	obj->thresholdMax = cv::getTrackbarPos("Max Bbar","BIN");
}


void on_Channeltrackbar(int argc,void* argv)
{
	FrameClass* obj = static_cast<FrameClass*>(argv);	
	obj->areaMin = cv::getTrackbarPos("Min Cbar","CH");
	obj->areaMax = cv::getTrackbarPos("Max Cbar","CH");
}

FrameClass::FrameClass():thresholdMin(200),thresholdMax(230)
{
#if 1
	cv::namedWindow("BIN",cv::WINDOW_AUTOSIZE);
	cv::createTrackbar("Min Bbar","BIN",NULL,255,on_Bintrackbar,this);
	cv::createTrackbar("Max Bbar","BIN",NULL,255,on_Bintrackbar,this);
	
	cv::namedWindow("CH",cv::WINDOW_AUTOSIZE);
	cv::createTrackbar("Min Cbar","CH",NULL,5000,on_Channeltrackbar,this);
	cv::createTrackbar("Max Cbar","CH",NULL,5000,on_Channeltrackbar,this);
#endif
}

FrameClass::~FrameClass()
{
	if(this->capture.isOpened()){
		this->capture.release();
	}
}


bool FrameClass::OpenVideo(int DeviceID)
{
	bool ret = false;
	this->capture.open(DeviceID);

	if(!capture.isOpened()){
		std::cout << "Open Video ID:" << DeviceID << "Failed" << std::endl;
		ret  = false;
	}else{
		ret = true;
	}

	return ret;
}

bool FrameClass::ReadImage(void)
{
	bool ret = false;
	this->capture.read(this->SrcImg);

	if(this->SrcImg.empty()){
		std::cout << "Frame read end" << std::endl;
		ret = false;
	}else{
		ret = true;
	}

	return ret;
}

void FrameClass::SetROI(int a,int b)
{
	this->width = this->SrcImg.cols;
	this->height = this->SrcImg.rows;
	this->cropWidth = this->width/a;
	this->cropHeight = this->height/b;
	this->x = (this->width - this->cropWidth)/2;
	this->y = (this->height -this->cropHeight)/2;
	cv::Rect roi(this->x,this->y,this->cropWidth,this->cropHeight);
	this->SrcImg(roi).copyTo(this->RoiImg);

}

void FrameClass::SplitChannels(int ch)
{
	cv::split(this->RoiImg,this->Channels);
	this->Channels[ch].copyTo(this->U8C1Img);
}

void FrameClass::Blur(void)
{
	cv::GaussianBlur(this->U8C1Img,this->BlurImg,cv::Size(3,3),0);
}


void FrameClass::Threshold(void)
{
	cv::threshold(this->BlurImg,this->BinaryImg,this->thresholdMin,this->thresholdMax,cv::THRESH_BINARY);
	//not good cv::adaptiveThreshold(this->U8C1Img,this->BinaryImg,255,cv::ADAPTIVE_THRESH_GAUSSIAN_C,cv::THRESH_BINARY,25,10);

	//cv::threshold(this->BlurImg,this->BinaryImg,this->thresholdMin,this->thresholdMax,cv::THRESH_BINARY | cv::THRESH_OTSU);
	//cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(3,3),cv::Point(-1,-1));
	//cv::erode(this->BinaryImg,this->BinaryImg,kernel);
}

void FrameClass::FindContours(void)
{
	cv::findContours(this->BinaryImg,this->contours,this->hirearchy,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE,cv::Point());
}

void FrameClass::DrawContours(void)
{
	for(size_t t = 0;t < this->contours.size();t++)
	{
		double area = cv::contourArea(this->contours[t]);
		double len = cv::arcLength(this->contours[t],true);
		if(area < this->areaMin ||  area > this->areaMax)
		{
			continue;
		}
		
		cv::Rect box = cv::boundingRect(this->contours[t]);
		box.x = this->x + box.x;
		box.y = this->y + box.y;
		cv::rectangle(this->SrcImg,box,cv::Scalar(0,0,255),2,8,0);
	}

	cv::drawContours(this->U8C1Img,this->contours,-1,cv::Scalar(0,0,255),2,8);
}


void FrameClass::ShowSrcImage(std::string WindowName)
{
	cv::imshow(WindowName,this->SrcImg);
}

void FrameClass::ShowChannelImage(std::string WindowName)
{

	cv::imshow(WindowName,this->U8C1Img);
}

void FrameClass::ShowBinaryImage(std::string WindowName)
{
	cv::imshow(WindowName,this->BinaryImg);
}


void FrameClass::ShowRoiImage(std::string WindowName)
{
	cv::imshow(WindowName,this->RoiImg);
}

void FrameClass::SaveImage(std::string Path)
{
	static unsigned int nu = 0;
	std::string bmpImageName = Path + "test_" + std::to_string(nu) + ".bmp";
	cv::imwrite(bmpImageName,this->SrcImg);
	std::cout << "Save Image " << bmpImageName << std::endl;
	nu ++;
}












